﻿using System;
using System.Runtime.Serialization;
using System.Text;
using Newtonsoft.Json;
using UFIDA.U9.Base.UserRole;
using UFIDA.U9.Base.UserRole.Proxy;
using UFIDA.U9.WSS.ProxyService.Exceptions;
using UFIDA.U9.WSS.ProxyService.Json;
using UFIDA.U9.WSS.ProxyService.Utils;
using UFIDA.UBF.SystemManage;
using UFIDA.UBF.SystemManage.Agent;
using UFSoft.UBF.Util.Log;
using Organization = UFIDA.U9.Base.Organization.Organization;

namespace UFIDA.U9.WSS.ProxyService.Models
{
    /// <summary>
    ///     上下文信息
    /// </summary>
    [DataContract]
    public class ContextInfo
    {
        private static readonly ILogger Logger = LoggerManager.GetLogger("ContextInfo");
        private string _culture = string.Empty;
        private string _supportCultureNameList = string.Empty;

        /// <summary>
        ///     企业ID
        /// </summary>
        [DataMember]
        public string EnterpriseID { get; set; }

        /// <summary>
        ///     企业名称
        /// </summary>
        [DataMember]
        public string EnterpriseName { get; set; }

        /// <summary>
        ///     组织ID
        /// </summary>
        [DataMember]
        public string OrgID { get; set; }

        /// <summary>
        ///     组织编码
        /// </summary>
        [DataMember]
        public string OrgCode { get; set; }

        /// <summary>
        ///     组织名称
        /// </summary>
        [DataMember]
        public string OrgName { get; set; }

        /// <summary>
        ///     用户ID
        /// </summary>
        [DataMember]
        public string UserID { get; set; }

        /// <summary>
        ///     用户编码
        /// </summary>
        [DataMember]
        public string UserCode { get; set; }

        /// <summary>
        ///     用户名称
        /// </summary>
        [DataMember]
        public string UserName { get; set; }

        /// <summary>
        ///     密码
        /// </summary>
        [DataMember]
        public string Password { get; set; }

        /// <summary>
        ///     语言
        /// </summary>
        [DataMember]
        public string Culture
        {
            get { return string.IsNullOrEmpty(_culture) ? Constant.DefaultContextCulture : _culture; }
            set { _culture = value; }
        }

        /// <summary>
        ///     支持语言列表，多个中间用,分隔
        /// </summary>
        [DataMember]
        public string SupportCultureNameList
        {
            get { return string.IsNullOrEmpty(_supportCultureNameList) ? Culture : _supportCultureNameList; }
            set { _supportCultureNameList = value; }
        }

        /// <summary>
        ///     是否初始化
        /// </summary>
        [JsonIgnore]
        public bool IsInit { get; set; }

        /// <summary>
        ///     验证及加载
        /// </summary>
        /// <param name="isNeedUserPasswordAuth">是否需要用户密码认证</param>
        public void ValidateAndInit(bool isNeedUserPasswordAuth)
        {
            IsInit = false;
            if (string.IsNullOrWhiteSpace(EnterpriseID))
                throw new WSException(ExceptionCodes.ContextInfoIncomplete, "enterpriseID is empty");
            if (string.IsNullOrWhiteSpace(OrgCode))
                throw new WSException(ExceptionCodes.ContextInfoIncomplete, "orgCode is empty");
            if (string.IsNullOrWhiteSpace(UserCode))
                throw new WSException(ExceptionCodes.ContextInfoIncomplete, "userCode is empty");
            Enterprise enterprise = GetEnterprise(EnterpriseID);
            if (enterprise == null)
                throw new WSException(ExceptionCodes.ContextEnterpriseIDNotExist,
                    string.Format("enterpriseID:{0} not exist", EnterpriseID));
            using (new SessionObject(enterprise, Culture, SupportCultureNameList))
            {
                Organization org = Organization.FindByCode(OrgCode);
                if (org == null)
                    throw new WSException(ExceptionCodes.ContextOrgCodeNotExist,
                        string.Format("org:{0} not exist", OrgCode));
                User user = User.FindByCode(UserCode);
                if (user == null)
                    throw new WSException(ExceptionCodes.ContextUserCodeNotExist,
                        string.Format("userCode:{0} not exist or password is incorrect", UserCode));
                //支持加密或未加密的
                if (isNeedUserPasswordAuth && Password != user.Password)
                {
                    try
                    {
                        LoginBPProxy loginBPProxy = new LoginBPProxy();
                        loginBPProxy.UserCode = UserCode;
                        loginBPProxy.Password = string.IsNullOrEmpty(Password) ? string.Empty : Password;
                        loginBPProxy.LanguageCode = Culture;
                        loginBPProxy.IP = string.Empty;
                        loginBPProxy.OrganizationId = org.ID;
                        loginBPProxy.EnterpriseId = -1;
                        LoginDataTransferObjectData loginDataTransferObjectData = loginBPProxy.Do();
                        if (!loginDataTransferObjectData.IsAccess)
                            throw new WSException(ExceptionCodes.ContextUserPasswordAuthFail, string.Format(
                                "userCode:{0} not exist or password is incorrect",
                                UserCode));
                    }
                    catch (Exception ex)
                    {
                        Logger.Error(ex);
                        throw new WSException(ExceptionCodes.ContextUserPasswordAuthFail, string.Format(
                            "userCode:{0} not exist or password is incorrect",
                            UserCode));
                    }
                }

                if (!user.IsAlive)
                    throw new WSException(ExceptionCodes.ContextUserIsNoAlive,
                        string.Format("userCode:{0} is not alive", UserCode));
                EnterpriseID = enterprise.Code;
                EnterpriseName = enterprise.Name;
                OrgID = org.ID.ToString();
                OrgCode = org.Code;
                OrgName = org.Name;
                UserID = user.ID.ToString();
                UserCode = user.Code;
                UserName = user.Name;
                IsInit = true;
            }
        }

        /// <summary>
        ///     获取企业信息
        /// </summary>
        /// <param name="enterpriseID"></param>
        /// <returns></returns>
        private static Enterprise GetEnterprise(string enterpriseID)
        {
            EnterpriseInfo enterpriseInfo = new EnterpriseInfo();
            return enterpriseInfo.GetEnterpriseByCode(enterpriseID);
        }

        /// <summary>
        ///     转为认证串
        /// </summary>
        /// <returns></returns>
        public string ToAuthString()
        {
            string jsonString = JsonHelper.ToJson(this);
            return Convert.ToBase64String(Encoding.UTF8.GetBytes(jsonString));
        }

        /// <summary>
        ///     从认证串转为对象
        /// </summary>
        /// <returns></returns>
        public static ContextInfo FromAuthString(string authString)
        {
            string jsonString = Encoding.UTF8.GetString(Convert.FromBase64String(authString));
            return JsonHelper.FromJson<ContextInfo>(jsonString);
        }
    }
}